//
//  HDBasicServiceHelper
//
//  Created by kopuCoder on 17/3/17.
//  Copyright © 2017年 kopuCoder. All rights reserved.
//

#import "HDCommonInfoHelper.h"
#import <UIKit/UIKit.h>
//#import <AddressBook/AddressBook.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#include <ifaddrs.h>
#include<arpa/inet.h>
#include<net/if.h>
#import "sys/utsname.h"
#import <AdSupport/AdSupport.h>

#pragma mark  -  WiFi相关
#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
#define IOS_VPN        @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"

#define KCurrentDevice [UIDevice currentDevice]
#define IOS10_OR_LATER		( [[KCurrentDevice systemVersion] compare:@"10.0"] != NSOrderedAscending )
#define kHelper


#define kDebug 0

@implementation HDPerson
- (NSMutableArray *)phoneNumbers{
    if (!_phoneNumbers) {
        _phoneNumbers = [[NSMutableArray alloc] init];
        
    }
    return _phoneNumbers;
}
@end


@implementation HDPlacemark
- (id)mutableCopyWithZone:(NSZone *)zone {
    HDPlacemark *copy = [[[self class] allocWithZone:zone] init];
    copy->_country = [self.country mutableCopy];
    copy->_province = [self.province mutableCopy];
    copy->_city = [self.city mutableCopy];
    copy->_county = [self.county mutableCopy];
    copy->_address = [self.address mutableCopy];
    copy->_placemarkId = self.placemarkId;
    copy->_type = [self.type mutableCopy];
    return copy;
}

- (id)copyWithZone:(NSZone *)zone {
    HDPlacemark *copy = [[[self class] allocWithZone:zone] init];
    copy->_country = [self.country copy];
    copy->_province = [self.province copy];
    copy->_city = [self.city copy];
    copy->_county = [self.county copy];
    copy->_address = [self.address copy];
    copy->_placemarkId = self.placemarkId;
    copy->_type = [self.type copy];
    return copy;
}

- (NSString *)city {
    NSString *cityName = _city;
    if ([cityName hasSuffix:@"市辖区"]) {
        cityName = [cityName substringToIndex:[cityName length] - 3];
    }
    if ([cityName hasSuffix:@"市"]) {
        cityName = [cityName substringToIndex:[cityName length] - 1];
    }
    if ([cityName isEqualToString:@"香港特別行政區"] || [cityName isEqualToString:@"香港特别行政区"]) {
        cityName = @"香港";
    }
    if ([cityName isEqualToString:@"澳門特別行政區"] || [cityName isEqualToString:@"澳门特别行政区"]) {
        cityName = @"澳门";
    }
    return cityName;
}

- (NSString *)province {
    NSString *provinceName = _province;
    if ([provinceName hasSuffix:@"省"]) {
        provinceName = [provinceName substringToIndex:[provinceName length] - 1];
    } else if ([provinceName hasSuffix:@"市"]) {
        provinceName = [provinceName substringToIndex:[provinceName length] - 1];
    }
    return provinceName;
}

- (NSString *)getProvinceAndCity {
    NSString *provinceName = _province ? : @"";
    NSString *cityName = _city ? : @"";
    if ([self.city isEqualToString:self.province]) {
        provinceName = @"";
    }
    if ([cityName hasSuffix:@"市辖区"]) {
        cityName = [cityName substringToIndex:[cityName length] - 3];
    }
    if ([cityName isEqualToString:@"香港特別行政區"] || [cityName isEqualToString:@"香港特别行政区"]) {
        cityName = @"香港";
    }
    if ([cityName isEqualToString:@"澳門特別行政區"] || [cityName isEqualToString:@"澳门特别行政区"]) {
        cityName = @"澳门";
    }
    return [provinceName stringByAppendingString:cityName];
}

+ (HDPlacemark *)initWithCLPlacemark:(CLPlacemark *)placemark {
    HDPlacemark *mark = [[HDPlacemark alloc] init];
    mark.country = placemark.country ? placemark.country : @"";
    mark.province = placemark.administrativeArea ? placemark.administrativeArea : @"";
    mark.city = placemark.locality ? placemark.locality : mark.province;
    mark.county = placemark.subLocality ? placemark.subLocality : @"";
    NSString *formatAddress = [NSString stringWithFormat:@"%@%@", placemark.thoroughfare ? placemark.thoroughfare : @"",
                               placemark.subThoroughfare ? placemark.subThoroughfare:@""];
    mark.address = formatAddress;
    return mark;
}

@end

#pragma mark ---设备信息模型---

@implementation HDDeviceModel
@end


#pragma mark ---deal tool---
@interface NSString (HDUtilities)
- (BOOL)containsString:(NSString *)aString;
- (NSString*)initTelephoneWithReformat;
@end

@implementation NSString (HDUtilities)
- (BOOL)containsString:(NSString *)aString
{
    NSRange range = [[self lowercaseString] rangeOfString:[aString lowercaseString]];
    return range.location != NSNotFound;
}

- (NSString * )initTelephoneWithReformat
{
    
    if ([self containsString:@"+86 "])
    {
        self = [self stringByReplacingOccurrencesOfString:@"+86 " withString:@""];
    }
    
    if ([self containsString:@"+86"])
    {
        self = [self stringByReplacingOccurrencesOfString:@"+86" withString:@""];
    }
    
    if ([self containsString:@"-"])
    {
        self = [self stringByReplacingOccurrencesOfString:@"-" withString:@""];
    }
    
    if ([self containsString:@" "])
    {
        self = [self stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    
    if ([self containsString:@"("])
    {
        self = [self stringByReplacingOccurrencesOfString:@"(" withString:@""];
    }
    
    if ([self containsString:@")"])
    {
        self = [self stringByReplacingOccurrencesOfString:@")" withString:@""];
    }
    
    return self;
}

@end

@interface HDCommonInfoHelper()

@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLGeocoder *geocoder;
@property (nonatomic, copy) GPSCoorClosure coorClosure;

/** */
@property (nonatomic,assign)CLLocationCoordinate2D tempCoordinate;


/**反地理编码回调block*/
@property (nonatomic, copy) void(^reverseCoordinateCallBack)(BOOL hasAuthor,CLLocationCoordinate2D coordinate,HDPlacemark * _Nullable reverseLocation);


@end
@implementation HDCommonInfoHelper

+ (HDCommonInfoHelper *)shareInstance {
    static HDCommonInfoHelper *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[HDCommonInfoHelper alloc] init];
    });
    return manager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        _locationManager.distanceFilter = kCLDistanceFilterNone ;//10;
        
        
        if ([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            // iOS8.0以上，使用应用程序期间允许访问位置数据
            [_locationManager requestWhenInUseAuthorization];
        }
        
        _geocoder = [[CLGeocoder alloc] init];
    }
    return self;
}




#pragma mark ---system addressBook---
/**检查系统通讯录权限*/
//+(void)CheckAddressBookAuthorization:(nullable void (^)(bool isAuthorized))block
//{
//    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
//    ABAuthorizationStatus authStatus = ABAddressBookGetAuthorizationStatus();
//    
//    if (authStatus != kABAuthorizationStatusAuthorized)
//    {
//        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
//                                                 {
//                                                     dispatch_async(dispatch_get_main_queue(), ^{
//                                                         if (error)
//                                                         {
//                                                             GYNLog(@"Error: %@", (__bridge NSError *)error);
//                                                         }
//                                                         else if (!granted)
//                                                         {
//                                                             
//                                                             block(NO);
//                                                         }
//                                                         else
//                                                         {
//                                                             block(YES);
//                                                         }
//                                                     });
//                                                 });
//    }
//    else
//    {
//        block(YES);
//    }
//    
//}

/**获取系统通讯录信息*/
//+ (void)getSystemAddressBookInfoWithCallBack:(void(^)(BOOL hasAuthor,NSArray<HDPerson *> * books))callBack{
//    
//    [HDCommonInfoHelper CheckAddressBookAuthorization:^(bool isAuthorized) {
//        
//        if(!isAuthorized){
//            dispatch_async(dispatch_get_main_queue(), ^{
//                
////                UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:kDeviceAuthorFlag message:kDeviceAddressBookInfo delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:@"去设置",nil];
////                alertView.tag = 1001;
////                [alertView show];
//                [CustomAlertView alertShowTitle:kDeviceAuthorFlag message:kDeviceAddressBookInfo cancelButtonTitle:@"知道了" otherButtonTitles:@"去设置" block:^(NSInteger buttonIndex) {
//                    if (buttonIndex==1) {
//                            [HDCommonInfoHelper OpenSystemContact];//打开通讯录
//                            return;
//                    }
//                }];
//                
//                
//            });
//            
//            if(callBack){ callBack(NO,nil); }
//            return;
//        }
//        
//        NSMutableArray * addressBookArray = [[NSMutableArray alloc] init];
//        
//        CFErrorRef error = NULL;
//        ABAddressBookRef addressBooks = ABAddressBookCreateWithOptions(NULL, &error);
//        
//        dispatch_semaphore_t sema = dispatch_semaphore_create(0);//发出访问通讯录的请求
//        ABAddressBookRequestAccessWithCompletion(addressBooks, ^(bool granted, CFErrorRef error) {
//            
//            dispatch_semaphore_signal(sema);
//        });
//        
//        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
//        
//        CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBooks);
//        CFIndex nPeople = ABAddressBookGetPersonCount(addressBooks);
//        
//        
//        for (NSInteger i = 0; i < nPeople; i++)
//        {
//            HDPerson *addressBook = [[HDPerson alloc] init];
//            ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
//            CFStringRef abName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
//            CFStringRef abLastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
//            CFStringRef abFullName = ABRecordCopyCompositeName(person);
//            
//            
//            NSString *nameString = (__bridge NSString *)abName;
//            NSString *lastNameString = (__bridge NSString *)abLastName;
//            
//            if ((__bridge id)abFullName != nil) {
//                nameString = (__bridge NSString *)abFullName;
//            } else {
//                if ((__bridge id)abLastName != nil)
//                {
//                    nameString = [NSString stringWithFormat:@"%@ %@", nameString, lastNameString];
//                }
//            }
//            
//            addressBook.name = nameString.length>0?nameString:@"";
//            
//            ABPropertyID multiProperties[] = {
//                kABPersonPhoneProperty,  // 电话
//                kABPersonEmailProperty   // 邮件
//            };
//            NSInteger multiPropertiesTotal = sizeof(multiProperties) / sizeof(ABPropertyID);
//            for (NSInteger j = 0; j < multiPropertiesTotal; j++) {
//                ABPropertyID property = multiProperties[j];
//                ABMultiValueRef valuesRef = ABRecordCopyValue(person, property);
//                NSInteger valuesCount = 0;
//                if (valuesRef != nil) valuesCount = ABMultiValueGetCount(valuesRef);
//                
//                if (valuesCount == 0) {
//                    CFRelease(valuesRef);
//                    continue;
//                }
//                
//                for (NSInteger k = 0; k < valuesCount; k++) {
//                    CFStringRef value = ABMultiValueCopyValueAtIndex(valuesRef, k);
//                    switch (j) {
//                        case 0: {// Phone number
//                            
//                            NSString * tempPhone =  [(__bridge NSString*)value initTelephoneWithReformat];
//                            
//                            if(tempPhone){
//                                [addressBook.phoneNumbers addObject:tempPhone];
//                            }
//#if kDebug
//                            GYNLog(@"name:%@---->PhoneNum:%@",addressBook.name,tempPhone);
//#endif
//                            
//                            break;
//                        }
//                        case 1: {// Email
//                            addressBook.email = (__bridge NSString*)value;
//                            break;
//                        }
//                    }
//                    CFRelease(value);
//                }
//#if kDebug
//                GYNLog(@"-------------------------------");
//#endif
//                
//                CFRelease(valuesRef);
//            }
//            
//            [addressBookArray addObject:addressBook];
//            
//            if (abName) CFRelease(abName);
//            if (abLastName) CFRelease(abLastName);
//            if (abFullName) CFRelease(abFullName);
//        }
//        
//        CFRelease(allPeople);
//        CFRelease(addressBooks);
//        
//        if(callBack){
//            callBack(YES,addressBookArray);
//        }
//    }];
//}



#pragma mark ---system location service---

/**检测是否开启定位服务以及是否授权地位
 servicesEnabled: 是否开启定位服务
 isAuthor:        是否授权定位
 */
+ (void)checkLocationServicesEnabledAndAuthorization:(void(^)(BOOL servicesEnabled,BOOL isAuthor))callBack{
    
    BOOL enableService = [HDCommonInfoHelper locationServicesEnabled];
    if(!enableService){
        if(callBack){
            callBack(NO,NO);
        }
    }
    
    CLAuthorizationStatus GPSStatus = [CLLocationManager authorizationStatus];
    
    switch (GPSStatus) {
        case kCLAuthorizationStatusDenied:
        {
            GYNLog(@"kCLAuthorizationStatusDenied");
        }break;
        case kCLAuthorizationStatusRestricted :{
            GYNLog(@"kCLAuthorizationStatusRestricted");
        }break;
        case kCLAuthorizationStatusNotDetermined :{
            GYNLog(@"kCLAuthorizationStatusNotDetermined");
        }break;
        case kCLAuthorizationStatusAuthorizedAlways :{
            GYNLog(@"kCLAuthorizationStatusAuthorizedAlways");
        }break;
        case kCLAuthorizationStatusAuthorizedWhenInUse :{
            GYNLog(@"kCLAuthorizationStatusAuthorizedWhenInUse");
        }break;
            
        default:
            break;
    }
    //如果没有授权则请求用户授权
    if (kCLAuthorizationStatusDenied == GPSStatus||kCLAuthorizationStatusRestricted == GPSStatus){
        
        //未授权
        if(callBack){
            callBack(YES,NO);
        }
        
    }else if(GPSStatus == kCLAuthorizationStatusAuthorizedWhenInUse||kCLAuthorizationStatusAuthorizedAlways ==  GPSStatus){
        
        //授权
        if(callBack){
            callBack(YES,YES);
        }
    }
    
    if(kCLAuthorizationStatusNotDetermined ==  GPSStatus){
        [HDCommonInfoHelper requestGPSWhenInUseAuthorization];
        //授权
        if(callBack){
            callBack(YES,YES);
        }
    }
}


/**请求定位授权 --->弹窗显示请求授权*/
+ (void)requestGPSWhenInUseAuthorization{
    CLLocationManager *locationManager = [HDCommonInfoHelper shareInstance].locationManager;
    [locationManager requestWhenInUseAuthorization];
}


/**打开系统相册访问权限设置*/
+ (void)OpenSystemPhotosLibrary{
    
    NSString * url = @"Prefs:root=Photos";
    [self openScheme:url callBack:^(BOOL success) {
        
        if(success){
            return;
        }
        
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }];
    /*
     NSURL *URL = [NSURL URLWithString:url];
     if ([[UIApplication sharedApplication] canOpenURL:URL]) {
     [[UIApplication sharedApplication] openURL:URL];
     } else {
     [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
     }
     */
}

+ (void )openScheme:(NSString *)scheme callBack:(void(^)(BOOL success))finish{
    UIApplication *application = [UIApplication sharedApplication];
    
    if(IOS10_OR_LATER){
        scheme = [scheme stringByReplacingOccurrencesOfString:@"prefs:" withString:@"Prefs:"];
    }
    NSURL *URL = [NSURL URLWithString:scheme];
    
    if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
        NSDictionary *options = @{UIApplicationOpenURLOptionUniversalLinksOnly : @YES};
        
        [application openURL:URL options:options
           completionHandler:^(BOOL success) {
               
               if(finish){
                   finish(success);
               }
               
           }];
    } else {
        BOOL success = [application openURL:URL];
        if(finish){
            finish(success);
        }
    }
}

/**打开系统通讯录设置*/
+ (void)OpenSystemContact{
    
    NSString * url = @"prefs:root=Privacy&path=CONTACTS";
    [self openScheme:url callBack:^(BOOL success) {
        
        if(success){
            return;
        }
        
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }];
}

+ (NSString *)checkiOS10Suffix:(NSString *)url{
    if(url.length == 0) return url;
    if(IOS10_OR_LATER){
        url = [url stringByReplacingOccurrencesOfString:@"prefs" withString:@"Prefs"];
    }
    return url;
    
}

/**打开系统定位设置*/
+ (void)OpenSystemLocation{
    
    NSString * url = @"prefs:root=LOCATION_SERVICES";
    [self openScheme:url callBack:^(BOOL success) {
        
        if(success){
            return;
        }
        
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }];
}



+ (void)getSystemGPServiceWithCallBack:(nullable void(^)(BOOL hasAuthor,CLLocationCoordinate2D coordinate,HDPlacemark * _Nullable reverseLocation))callBack{
    
    //检查权限
    [HDCommonInfoHelper checkLocationServicesEnabledAndAuthorization:^(BOOL servicesEnabled, BOOL isAuthor) {
        NSString * msg = nil;
        if(!servicesEnabled){
            msg = kDeviceGPSServiceInfo;
//            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:kDeviceAuthorFlag message:msg delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles: nil];
//            [alertView show];
            
            [CustomAlertView alertShowTitle:kDeviceAuthorFlag message:msg cancelButtonTitle:@"知道了" otherButtonTitles:nil block:^(NSInteger buttonIndex) {
            }];
            
            
            
            
            return;
        }
        
        
        if(!isAuthor){
            msg =kGPSAuthorInfo;
            
//            HDCommonInfoHelper * manager = [HDCommonInfoHelper shareInstance];
            [HDCommonInfoHelper requestGPSWhenInUseAuthorization];
//            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:kDeviceAuthorFlag message:msg delegate:manager cancelButtonTitle:@"知道了" otherButtonTitles:@"去设置",nil];
//            [alertView show];
//            
            [CustomAlertView alertShowTitle:kDeviceAuthorFlag message:msg cancelButtonTitle:@"知道了" otherButtonTitles:@"去设置" block:^(NSInteger buttonIndex) {
                if(buttonIndex==1){
                    [HDCommonInfoHelper OpenSystemLocation];//打开定位设置
                    return;
                }
                
            }];
            
            
            
            return;
        }
        
        if(callBack){
            HDCommonInfoHelper * manager = [HDCommonInfoHelper shareInstance];
            manager.reverseCoordinateCallBack = [callBack copy];
        }
        
        
        
        [HDCommonInfoHelper getGPSLocation:^(CLLocationDegrees latitude, CLLocationDegrees longitude) {
            HDCommonInfoHelper * manager = [HDCommonInfoHelper shareInstance];
            manager.tempCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
            
            [HDCommonInfoHelper getPlacemarkWithLatitude:[NSString stringWithFormat:@"%lf",latitude] longitude:[NSString stringWithFormat:@"%lf",longitude] closure:^(HDPlacemark * _Nullable placemark) {
               
                HDCommonInfoHelper * manager = [HDCommonInfoHelper shareInstance];
                if(manager.reverseCoordinateCallBack){
                    manager.reverseCoordinateCallBack(YES,manager.tempCoordinate,placemark);
                }
                [HDCommonInfoHelper stop];
            }];
        }];
        
    }];
}


//- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
//    
//    if(buttonIndex < 1) return;
//    if(1001 == alertView.tag){
//    
//        [HDCommonInfoHelper OpenSystemContact];//打开通讯录
//        return;
//    }
//    [HDCommonInfoHelper OpenSystemLocation];//打开定位设置
//}

- (void)getGPS:(GPSCoorClosure)closure {
    if ([CLLocationManager locationServicesEnabled] == NO) {
        return;
    }
    _coorClosure = closure;
    // 停止上一次定位
    [_locationManager stopUpdatingLocation];
    // 开始新一次定位
    [_locationManager startUpdatingLocation];
}

- (void)getPlacemarkWithCoor:(CLLocationCoordinate2D)coor closure:(GPSPlacemarkClosure)closure {
    CLLocation *location = [[CLLocation alloc] initWithLatitude:coor.latitude longitude:coor.longitude];
    [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count > 0) {
            CLPlacemark *placemark = placemarks.lastObject;
            HDPlacemark *mark = [HDPlacemark initWithCLPlacemark:placemark];
            if (closure) {
                closure(mark);
            }
        }
    }];
}


- (void)getGPSLocationWithAddress:(NSString *)address closure:(GPSCoorClosure)closure {
    [_geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count > 0) {
            CLPlacemark *placemark = placemarks.lastObject;
            
            if (closure) {
                closure(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
            }
        }
    }];
}


#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    CLLocation *location = locations.lastObject;
    CLLocationDegrees lat = location.coordinate.latitude;
    CLLocationDegrees lng = location.coordinate.longitude;
    GYNLog(@"当前更新位置: 纬度: (%lf), 经度: (%lf)", lat, lng);
    
    if (_coorClosure) {
        _coorClosure(lat, lng);
    }
}


/**定位失败*/
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    
    if (error.code == kCLErrorDenied) {
        [[HDCommonInfoHelper shareInstance] stop];
        GYNLog(@"访问被拒绝");
    } else if (error.code == kCLErrorLocationUnknown) {
        GYNLog(@"无法获取位置信息");
        [[HDCommonInfoHelper shareInstance] stop];
    }
}



- (void)stop {
    [_locationManager stopUpdatingLocation];
}



#pragma mark - 临时开放
+ (void)getGPSLocation:(GPSCoorClosure)closure {
    [[HDCommonInfoHelper shareInstance] getGPS:closure];
}


+ (void)stop {
    [[HDCommonInfoHelper shareInstance] stop];
}

+ (BOOL)locationServicesEnabled {
    return [CLLocationManager locationServicesEnabled];
}



+ (void)getPlacemarkWithLatitude:(NSString *)latitude longitude:(NSString *)longitude closure:(GPSPlacemarkClosure)closure {
    CLLocationCoordinate2D coor = CLLocationCoordinate2DMake([latitude doubleValue], [longitude doubleValue]);
    [[HDCommonInfoHelper shareInstance] getPlacemarkWithCoor:coor closure:closure];
}

+ (void)getPlacemarkWithCoordinate2D:(CLLocationCoordinate2D)coor closure:(GPSPlacemarkClosure)closure {
    [[HDCommonInfoHelper shareInstance] getPlacemarkWithCoor:coor closure:closure];
}

+ (void)getGPSLocationWithAddress:(NSString *)address closure:(GPSCoorClosure)closure {
    [[HDCommonInfoHelper shareInstance] getGPSLocationWithAddress:address closure:closure];
}


#pragma mark ---Device basic info---

+ (HDDeviceModel *)getCurrentDeviceInfoModel{
   
    HDDeviceModel * deviceModel = [[HDDeviceModel alloc] init];
    
    deviceModel.DeviceAdvertisingIdentifier = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getDeviceAdvertisingIdentifier] appdingName:@"IDFA:"];
    
    deviceModel.DeviceUUID = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getDeviceUUID] appdingName:@"UDID:"];

    
    deviceModel.DeviceSystemName = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getDeviceSystemName] appdingName:@"设备系统名:"];
    
    
    deviceModel.DeviceVersion =  [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getDeviceVersion] appdingName:@"设备系统版本:"];
    
    
    deviceModel.DeviceModel = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getDeviceModel] appdingName:@"设备类型:"];
    
    
    deviceModel.AppName = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getAppName] appdingName:@"当前App:"];
    
    
    deviceModel.AppVersion = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getAppVersion] appdingName:@"当前App版本:"];
    
    deviceModel.DeviceModelName = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getDeviceModelName] appdingName:@"当前设备类型:"];
    

    
    deviceModel.deviceIPAdress = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper deviceIPAdress] appdingName:@"当前设备IP地址:"];
    

    deviceModel.WifiName = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper getWifiName] appdingName:@"当前连接wifi名称:"];
    
    deviceModel.fetchSSIDInfo = [HDCommonInfoHelper formateDeviceInfoWithoriginInfo:[HDCommonInfoHelper fetchSSIDInfo] appdingName:@"当前设备连接Wi-Fi名称与MAC地址:"];
    return deviceModel;
}

+ (NSString *)formateDeviceInfoWithoriginInfo:(NSString *)originInfo appdingName:(NSString *)name{
    
   return  [NSString stringWithFormat:@"%@%@",name,originInfo];
}

+ (NSString * _Nonnull)getDeviceAdvertisingIdentifier{
    NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    return adId.length >0?adId:@"";
}

+ (NSString * _Nonnull )getDeviceUUID{
    
    NSString * tempString = [[KCurrentDevice identifierForVendor] UUIDString];
    return tempString.length >0?tempString:@"";
    
}

+ (NSString * _Nonnull )getDeviceSystemName{
    
    NSString * tempString = [KCurrentDevice systemName];
    return tempString.length >0?tempString:@"";
    
    
}

+ (NSString * _Nonnull )getDeviceVersion{
    
    NSString * tempString = [KCurrentDevice systemVersion];
    return tempString.length >0?tempString:@"";
    
}

+ (NSString * _Nonnull )getDeviceModel{
    
    NSString * tempString = [KCurrentDevice model];
    return tempString.length >0?tempString:@"";
    
}

+ (NSString * _Nonnull )getDeviceLocalModel{
    
    NSString * tempString = [KCurrentDevice localizedModel];
    return tempString.length >0?tempString:@"";
    
    
}

+ (NSString * _Nonnull )getAppName{
    
    NSDictionary * infoDic = [[NSBundle mainBundle] infoDictionary];
    
    NSString * tempString = [infoDic objectForKey:@"CFBundleDisplayName"];
    return tempString.length >0?tempString:@"";
}

+ (NSString * _Nonnull )getAppVersion{
    
    NSDictionary * infoDic = [[NSBundle mainBundle] infoDictionary];
    NSString * tempString = [infoDic objectForKey:@"CFBundleShortVersionString"];
    
    return tempString.length >0?tempString:@"";
    
}

+ (NSString * _Nonnull )getAppVersionNum{
    
    NSDictionary * infoDic = [[NSBundle mainBundle] infoDictionary];
    NSString * tempString = [infoDic objectForKey:@"CFBundleShortVersionString"];
    return tempString.length >0?tempString:@"";
    
}

+ (NSString * _Nonnull )getAppInfo{
    
    NSString * tempString = [[[NSBundle mainBundle] infoDictionary] description];
    return tempString.length >0?tempString:@"";
}

+ (NSString * _Nonnull )getDeviceModelName {
    // 需要#import "sys/utsname.h"
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    
    //iPhone
    if ([deviceString isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    if ([deviceString isEqualToString:@"iPhone5,1"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,2"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,3"])    return @"iPhone 5C";
    if ([deviceString isEqualToString:@"iPhone5,4"])    return @"iPhone 5C";
    if ([deviceString isEqualToString:@"iPhone6,1"])    return @"iPhone 5S";
    if ([deviceString isEqualToString:@"iPhone6,2"])    return @"iPhone 5S";
    if ([deviceString isEqualToString:@"iPhone7,1"])    return @"iPhone 6 Plus";
    if ([deviceString isEqualToString:@"iPhone7,2"])    return @"iPhone 6";
    if ([deviceString isEqualToString:@"iPhone8,1"])    return @"iPhone 6s";
    if ([deviceString isEqualToString:@"iPhone8,2"])    return @"iPhone 6s Plus";
    if ([deviceString isEqualToString:@"i386"])         return @"Simulator";
    if ([deviceString isEqualToString:@"x86_64"])       return @"Simulator";
    
    return @"";
}

//IP地址
+ (NSString *)deviceIPAdress {
    NSString *address = @"an error occurred when obtaining ip address";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    
    success = getifaddrs(&interfaces);
    
    if (success == 0) { // 0 表示获取成功
        
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            if( temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                }
            }
            
            temp_addr = temp_addr->ifa_next;
        }
    }
    
    freeifaddrs(interfaces);
    return address.length >0?address:@"";
}

//当前手机连接的WIFI名称(SSID)
+ (NSString *)getWifiName
{
    NSString *wifiName = nil;
    
    CFArrayRef wifiInterfaces = CNCopySupportedInterfaces();
    if (!wifiInterfaces) {
        return @"";
    }
    
    NSArray *interfaces = (__bridge NSArray *)wifiInterfaces;
    
    for (NSString *interfaceName in interfaces) {
        CFDictionaryRef dictRef = CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interfaceName));
        
        if (dictRef) {
            NSDictionary *networkInfo = (__bridge NSDictionary *)dictRef;
            
            wifiName = [networkInfo objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
            
            CFRelease(dictRef);
        }
    }
    
    CFRelease(wifiInterfaces);
    
    NSString * tempString = [NSString stringWithFormat:@"%@",wifiName];
    return tempString.length >0?tempString:@"";
}

//获取当前连接Wi-Fi名称与MAC地址
+(id)fetchSSIDInfo {
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    GYNLog(@"Supported interfaces: %@", ifs);
    id info = nil;
    for (NSString *ifnam in ifs) {
        info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        GYNLog(@"ifnam:%@ =>info:%@", ifnam, info);
        if (info && [info count]) { break;
        }
    }
    return info?info:@"";
}

//获取当前连接Wi-Fi的IP地址
+ (NSString *)getIPAddress:(BOOL)preferIPv4 {
    NSArray *searchArray = preferIPv4 ?
    @[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6,       IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
    NSDictionary *addresses = [self getIPAddresses];
    GYNLog(@"addresses: %@", addresses);
    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
        address = addresses[key];
        if(address) *stop = YES;
    } ];
    return address ? address : @"0.0.0.0";
    
}

+ (NSDictionary *)getIPAddresses {
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : addresses;
}


+ (NSString *)deviceNetworkTechnology{
    // be sure to import the library <CoreTelephony/CTTelephonyNetworkInfo.h> and <CoreTelephony/CTCarrier.h>
    CTTelephonyNetworkInfo *teleNetworkInfo = [[CTTelephonyNetworkInfo alloc] init];
    NSString *currentStatus = teleNetworkInfo.currentRadioAccessTechnology;
    
    if ([currentStatus isEqualToString:CTRadioAccessTechnologyGPRS]) {
        return @"GPRS";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyEdge]) {
        return @"Edge";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyWCDMA]) {
        return @"WCDMA";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyHSDPA]) {
        return @"HSDPA";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyHSUPA]) {
        return @"HSUPA";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
        return @"CDMA1x";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
        return @"CDMAEVDORev0";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
        return @"CDMAEVDORevA";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
        return @"CDMAEVDORevB";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyeHRPD]) {
        return @"HRPD";
    } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyLTE]) {
        return @"LTE";
    } else {
        return @"";
    }
}

+ (void)testDebug{
    
     GYNLog(@"IP地址====%@",[HDCommonInfoHelper deviceIPAdress]);
     GYNLog(@"当前手机连接的WIFI名称(SSID)====%@",[HDCommonInfoHelper getWifiName]);
     GYNLog(@"获取当前连接Wi-Fi名称与MAC地址====%@",[HDCommonInfoHelper fetchSSIDInfo]);
     GYNLog(@"获取当前连接Wi-Fi的IP地址====%@",[HDCommonInfoHelper getIPAddress:YES]);

}



@end
